package com.zbl.zblproject.erp.controller;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zbl.zblproject.core.entity.*;
import com.zbl.zblproject.core.mapper.*;
import com.zbl.zblproject.core.service.OrderService;
import com.zbl.zblproject.core.utils.ResultUtil;
import com.zbl.zblproject.core.utils.TimeUtil;
import com.zbl.zblproject.erp.entity.*;
import com.zbl.zblproject.erp.mapper.ErpFinanceLogMapper;
import com.zbl.zblproject.erp.mapper.ErpOrderItemMapper;
import com.zbl.zblproject.erp.service.ErpOrderService;
import com.zbl.zblproject.erp.service.ErpTableService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.*;

/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/10/23
 * ERP报表接口
 */
@Api(tags = {"ERP报表接口"})
@RestController
@RequestMapping("/erp-table")
public class ErpTableController {

    @Autowired
    private ErpTableService erpTableService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserAddressMapper addressMapper;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private ErpOrderItemMapper erpOrderItemMapper;

    @Autowired
    private ErpFinanceLogMapper erpFinanceLogMapper;


    private static final Logger logger = LoggerFactory.getLogger(ErpTableController.class);

    @GetMapping("/owe")
    @ApiOperation("欠缺货表单")
    public Result oweTable() {
        ErpOweTableContainer container = erpTableService.getAllOweTable();
        if (container.isEmpty()) {
            return ResultUtil.error("没有数据!");
        }
        return ResultUtil.success("成功!", container);
    }

    @GetMapping("/stock")
    @ApiOperation("时间段内所有的库存汇总")
    public Result stockAll(@ApiParam("开始时间") @RequestParam("start") String startTime,
                           @ApiParam("结束时间") @RequestParam("end") String endTime) {
        try {
            logger.info("查询库存汇总时间区间 {} -- {}", startTime, endTime);
            LocalDateTime start = TimeUtil.parseTime(startTime);
            LocalDateTime end = TimeUtil.parseTime(endTime);
            return ResultUtil.success("成功", erpTableService.getAllStockTable(start, end));
        } catch (DateTimeParseException e) {
            return ResultUtil.error("时间格式错误!");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }


    @GetMapping("/stock/{current}/{size}")
    @ApiOperation("库存汇总")
    public Result stockComputer(@ApiParam("开始时间") @RequestParam("start") String startTime,
                                @ApiParam("结束时间") @RequestParam("end") String endTime,
                                @ApiParam("当前页") @PathVariable int current,
                                @ApiParam("数量") @PathVariable int size) {
        try {
            logger.info("查询库存汇总时间区间 {} -- {}", startTime, endTime);
            LocalDateTime start = TimeUtil.parseTime(startTime);
            LocalDateTime end = TimeUtil.parseTime(endTime);
            return ResultUtil.success("成功", erpTableService.getStockTableByTime(start, end, current, size));
        } catch (DateTimeParseException e) {
            return ResultUtil.error("时间格式错误!");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }

    @GetMapping("/stock/{current}/{size}/{mode}")
    @ApiOperation("库存汇总")
    public Result stockComputer(@ApiParam("开始时间") @RequestParam("start") String startTime,
                                @ApiParam("结束时间") @RequestParam("end") String endTime,
                                @ApiParam("当前页") @PathVariable int current,
                                @ApiParam("数量") @PathVariable int size,
                                @ApiParam("查询模式") @PathVariable int mode) {
        try {
            logger.info("查询库存汇总时间区间 {} -- {}", startTime, endTime);
            LocalDateTime start = TimeUtil.parseTime(startTime);
            LocalDateTime end = TimeUtil.parseTime(endTime);
            return ResultUtil.success("成功", erpTableService.getStockTableByTimeAndMode(start, end, current, size, mode));
        } catch (DateTimeParseException e) {
            return ResultUtil.error("时间格式错误!");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(e.getMessage());
        }
    }


    /**
     * 表示 (当前月-月份长度) == 开始月
     * 大于now的
     *
     * @param time 月份长度
     * @return
     */
    @GetMapping("/zombie-goods/{current}/{size}")
    @ApiOperation("未出入库的商品")
    public Result zombieGoods(@ApiParam("时长") @RequestParam("time") int time,
                              @ApiParam("页数") @PathVariable int current,
                              @ApiParam("数量") @PathVariable int size) {
        LocalDateTime now = LocalDateTime.now();
        now = now.minusMonths(time);
        logger.info("查询未出入库商品年限:{}", now.toString());
        return ResultUtil.success("成功!", erpTableService.getZombieGoodsByLastTime(now, current, size));
    }

    @GetMapping("/inout-order/{orderSn}")
    @ApiOperation("导出订单")
    public void downloadOutOrderExcel(@ApiParam("出库单号") @PathVariable String orderSn,
                                      HttpServletResponse res) {
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=output-detail.xls");
        try (OutputStream os = res.getOutputStream()) {
            List<ErpTempOrderItem> items = erpOrderService.getOrderItemByOrderNotDesc(orderSn);
            if (!items.isEmpty()) {
                ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
                Sheet sheet1 = new Sheet(1, 0);
                Table table1 = new Table(1);
                sheet1.setSheetName("sheet1");
                List<List<String>> data1 = new ArrayList<>();
                data1.add(Arrays.asList("订单编号:" + orderSn));
                data1.addAll(getTableItem(items));
                writer.write0(data1, sheet1, table1);
                writer.finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @GetMapping("/output-excel/{brandName}")
    @ApiOperation("导出所有的出库商品")
    public void downloadOutputExcel(@ApiParam("品牌名称") @PathVariable String brandName,
                                    HttpServletResponse res) {
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=output-detail.xls");
        try (OutputStream os = res.getOutputStream()) {
            //导出所有的改品牌的出库商品,不用合并,按订单号导出
            List<ErpOrder> orders = erpOrderService.selectErpOrderByBrandName(brandName, 1, 2);
            if (!orders.isEmpty()) {
                ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
                Sheet sheet1 = new Sheet(1, 0);
                Table table1 = new Table(1);
                sheet1.setSheetName("sheet1");
                List<List<String>> data1 = new ArrayList<>();
                for (ErpOrder order : orders) {
                    data1.add(Arrays.asList("用户名:" + order.getOperator(), "门店名:" + adminUserMapper.selectNameById(order.getStoreId()), "订单编号:" + order.getOrderInfo()));
                    data1.addAll(getTableItem(erpOrderService.getOrderItemByOrder(order.getOrderInfo())));
                }
                writer.write0(data1, sheet1, table1);
                writer.finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @GetMapping("/store-excel/{orderSn}")
    @ApiOperation("导出对应orderSn的Excel订单")
    public void downloadStoreExcel(@ApiParam("订单号") @PathVariable String orderSn,
                                   HttpServletResponse res) {
        List<ErpGoods> list = orderService.getGoodsByOrderSn(orderSn);
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=store-" + orderSn + ".xls");
        try (OutputStream os = res.getOutputStream()) {
            if (!list.isEmpty()) {
                ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("sheet1");
                //工厂名称
                Table table1 = new Table(1);
                List<List<String>> data1 = new ArrayList<>(1);
                Order order = orderMapper.selectByOrderSn(orderSn);
                UserAddress address = addressMapper.selectById(order.getAddressId());
                String addressStr = "";
                if (address != null) {
                    addressStr = address.getAddress();
                }
                data1.add(Arrays.asList("订单编号:" + orderSn, "收货地址:" + addressStr));
                data1.addAll(getTableItemForStore(list));
                writer.write0(data1, sheet1, table1);
                writer.finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @GetMapping("/detail-excel/{orderSn}")
    @ApiOperation("导出对应orderSn的Excel订单")
    public void downloadDetailExcel(@ApiParam("订单号") @PathVariable String orderSn,
                                    HttpServletResponse res) {
        List<ErpGoods> list = orderService.getGoodsByOrderSn(orderSn);
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=store-" + orderSn + ".xls");
        try (OutputStream os = res.getOutputStream()) {
            if (!list.isEmpty()) {
                ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("sheet1");
                //工厂名称
                Table table1 = new Table(1);
                List<List<String>> data1 = new ArrayList<>(1);
                Order order = orderMapper.selectByOrderSn(orderSn);
                UserAddress address = addressMapper.selectById(order.getAddressId());
                String addressStr = "";
                if (address != null) {
                    addressStr = address.getAddress();
                }
                data1.add(Arrays.asList("订单编号:" + orderSn, "收货地址:" + addressStr));
                data1.addAll(getTableItemForStore(list));
                List<UserFactoryOrder> orders = orderService.getGoodsForOrderSnChildren(orderSn);
                for (UserFactoryOrder userOrder : orders) {
                    data1.add(Arrays.asList("用户名:" + userOrder.getName(), "订单编号:" + userOrder.getOrderSn()));
                    data1.addAll(getTableItemForStore(orderService.getGoodsByOrderSn(userOrder.getOrderSn())));
                }
                writer.write0(data1, sheet1, table1);
                writer.finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @GetMapping("s-goods/{suplierId}/{whId}/{catId}")
    @ApiOperation("根据供应商,货架,类别查询列表数")
    public Result shelfAndSupplierGoods() {
        return ResultUtil.error("接口未开放!");
    }


    @GetMapping("/excel/{mode}/{factoryName}/{start}/{end}")
    @ApiOperation("导出Excel文件")
    public void downloadExcel(@ApiParam("工厂名称") @PathVariable String factoryName,
                              @ApiParam("模式:0:CGDD 1:工厂明细 2:合并门店订单") @PathVariable int mode,
                              @ApiParam("开始时间") @PathVariable String start,
                              @ApiParam("结束时间") @PathVariable String end,
                              HttpServletResponse res) {
        FactoryOrder factoryOrder;

        if (mode == 0) {
            factoryOrder = orderService.getSupplierOrderByName(factoryName, start, end);
        } else if (mode == 1) {
            factoryOrder = orderService.getSupplierOrderByNameForDownloadFactoryExcel(factoryName, start, end);
        } else {
            //合并门店订单
            factoryOrder = orderService.getSupplierOrderByMode2(factoryName, start, end);
        }
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=zbltable.xls");
        try (OutputStream os = res.getOutputStream()) {
            if (factoryOrder != null) {

                ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("sheet1");
                //工厂名称
                Table table1 = new Table(1);
                List<List<String>> data1 = new ArrayList<>(1);

                String orderSn = factoryOrder.getAllItem().get(0).getOrderSn();
                if (mode == 2) {
                    data1.add(Arrays.asList("厂家名称:" + factoryName));
                } else if (mode == 1) {
                    data1.add(Arrays.asList("厂家名称:" + factoryName));
                } else {
                    data1.add(Arrays.asList("厂家名称:" + factoryName, "订单号:" + orderSn));
                }
                data1.add(Arrays.asList("总和"));
                if (mode == 1) {
                    FactoryOrder cgddOrder = orderService.getSupplierOrderByName(factoryName, start, end);
                    data1.addAll(getTableItem(cgddOrder.getAllItem()));
                } else {
                    data1.addAll(getTableItem(factoryOrder.getAllItem()));
                }
                for (FactoryItem item : factoryOrder.getUserItem()) {
                    if (mode == 1) {
                        data1.add(Arrays.asList("门店名称:" + item.getName(), "订单号:" + item.getOrderSn()));
                    } else {
                        data1.add(Arrays.asList("门店名称:" + item.getName()));
                    }
                    data1.addAll(getTableItem(item.getItems()));
                }

                writer.write0(data1, sheet1, table1);
                writer.finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/suppliers-table/{current}/{size}")
    @ApiOperation("下载一定时间段内的采购和入库类")
    public Result downloadSuppliers2(@ApiParam("开始") @RequestParam("start") String start,
                                    @ApiParam("结束") @RequestParam("end") String end,
                                     @ApiParam("页数") @PathVariable int current,
                                     @ApiParam("项数") @PathVariable int size) {

        //序号, 供应商名称, 采购数量, 实际入库数量, 差异数量, 采购金额, 入库金额, 差异金额, 财务实付金额

        long startTime = TimeUtil.parseTimeToInstant(start);
        long endTime = TimeUtil.parseTimeToInstant(end);
        LocalDateTime startDate = TimeUtil.parseTime(start);
        LocalDateTime endDate = TimeUtil.parseTime(end);
        IPage<ErpTableEntity> page = new Page<>(current, size);
        page = supplierMapper.selectAllSupplierByPage(page);
        ErpTableEntity supplier;
        for (int i = 0; i < page.getRecords().size(); i++) {
            supplier = page.getRecords().get(i);
            if (supplier == null || supplier.getName() == null) {
                continue;
            }

            //查询出orderSn
            List<String> orderSn = orderMapper.selectOrderSnIsCgdd(supplier.getId(), startTime, endTime);
            logger.info("厂家:{} 厂家ID:{}  时间:{} 订单号:{}", supplier.getName(), supplier.getId(), startDate,orderSn);
            if(!orderSn.isEmpty()) {
                ErpTableEntity entity = erpOrderItemMapper.selectErpTableByOrderSn(orderSn);
                if (entity != null) {
                    supplier.setIntoNumber(entity.getIntoNumber());
                    supplier.setIntoPrice(entity.getIntoPrice());
                }
            }


            ErpTableEntity entity2 = supplierMapper.selectErpTableEntityBySupplier(supplier.getId(), startTime, endTime);
            if(entity2 != null) {
                supplier.setOrderNumber(entity2.getOrderNumber());
                supplier.setGoodsPrice(entity2.getGoodsPrice());
            }
            supplier.setFinishPrice(erpFinanceLogMapper.selectAllPriceBySupplierNameAndTime(supplier.getName(), startDate, endDate));
            List<ErpTableEntity> clients = adminUserMapper.selectErpTableEntity(supplier.getId(), startTime, endTime);
            for(ErpTableEntity client : clients){
                if(client == null){
                    continue;
                }

                List<String> orderSn2 = adminUserMapper.selectOrderSnByUserForStart(supplier.getId(), client.getId(), startTime, endTime);
                if(!orderSn2.isEmpty()) {
//                    ErpTableEntity tempClient = erpOrderItemMapper.selectUserTableEntity(supplier.getId(),
//                            client.getId(), startDate, endDate);
                    ErpTableEntity tempClient = erpOrderItemMapper.selectUserTableEntityByOrderSn(orderSn2);
                    if (tempClient != null) {
                        client.setIntoPrice(tempClient.getIntoPrice());
                        client.setIntoNumber(tempClient.getIntoNumber());
                    }
                }
                client.setFinishPrice(erpFinanceLogMapper.selectAllPriceBySupplierNameAndTime(client.getName(), startDate, endDate));
            }
            if(!clients.isEmpty()){
                supplier.setClients(clients);
            }
        }
        return ResultUtil.success("成功!", page);

    }



    @GetMapping("/sales-table")
    @ApiOperation("导出所有商品的销售报表")
    public void downloadSaleTable(HttpServletResponse res, @ApiParam("月份") @RequestParam("month") String[] data) {
        res.setContentType("multipart/form-data");
        res.setHeader("Content-disposition", "attachment;filename=sales.xls");
        try (OutputStream os = res.getOutputStream()) {
            ExcelWriter writer = new ExcelWriter(os, ExcelTypeEnum.XLS);
            Sheet sheet1 = new Sheet(1, 0);
            sheet1.setSheetName("sheet1");
            Table table1 = new Table(1);
            List<List<String>> data1 = new ArrayList<>(1);
            for (int i = 0; i < data.length; i++) {
                String month = data[i];
                data1.add(Arrays.asList("月份", month));
                //data1.add();
                data1.addAll(getTableItemForOrderItem(orderItemMapper.selectCgddOrderItemByMonth(month)));
            }
            writer.write0(data1, sheet1, table1);
            writer.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private List<List<String>> getTableItemForStore(List<ErpGoods> items) {
        List<List<String>> table = new ArrayList<>();
        if (items == null || items.isEmpty()) {
            return table;
        }
        List<String> head = new ArrayList<>();
        head.add("序号");
        head.add("商品名称");
        head.add("规格");
        head.add("生产厂家");
        head.add("订购数量");
        head.add("大单位包装数");
        head.add("单价");
        head.add("金额");
        table.add(head);
        List<String> item;
        ErpGoods orderItem;
        BigDecimal allPrice = new BigDecimal(0);
        int allNum = 0;
        for (int i = 0; i < items.size(); i++) {
            item = new ArrayList<>();
            orderItem = items.get(i);
            item.add(i + 1 + "");
            item.add(orderItem.getGoodsName());
            item.add(orderItem.getGoodsDesc());
            if (orderItem.getErpSupplier() != null) {
                item.add(orderItem.getErpSupplier().getSuppliersName());
            } else {
                item.add("");
            }
            item.add(String.valueOf(orderItem.getGoodsNumber()));
            item.add(String.valueOf(orderItem.getNumberUnit()));
            item.add(String.valueOf(orderItem.getShopPrice()));
            BigDecimal duckPrice = orderItem.getShopPrice().multiply(new BigDecimal(orderItem.getGoodsNumber()));
            item.add(duckPrice.toString());
            allPrice = allPrice.add(duckPrice);
            allNum += orderItem.getGoodsNumber();
            table.add(item);
        }
        item = new ArrayList<>();
        item.add("");
        item.add("");
        item.add("");
        item.add("");
        item.add("合计数量");
        item.add(allNum + "");
        item.add("合计金额");
        item.add(allPrice.toString());
        table.add(item);
        return table;
    }

    private List<List<String>> getTableItemForOrderItem(List<OrderItem> items) {
        List<List<String>> table = new ArrayList<>();
        if (items == null || items.isEmpty()) {
            return table;
        }
        List<String> head = new ArrayList<>();
        head.add("序号");
        head.add("商品名称");
        head.add("供应商名称");
        head.add("品牌");
        head.add("订购数量");
        head.add("单价");
        head.add("金额");
        table.add(head);
        List<String> item;
        OrderItem orderItem;
        BigDecimal allPrice = new BigDecimal(0);
        int allNum = 0;
        for (int i = 0; i < items.size(); i++) {
            item = new ArrayList<>();
            orderItem = items.get(i);
            item.add(i + 1 + "");
            item.add(orderItem.getGoodsName());
            item.add(orderItem.getSupplierName());
            item.add(orderItem.getBrandName());
            item.add(String.valueOf(orderItem.getGoodsNum()));
            item.add(String.valueOf(orderItem.getShopPrice()));
            BigDecimal duckPrice = orderItem.getShopPrice().multiply(new BigDecimal(orderItem.getGoodsNum()));
            item.add(duckPrice.toString());
            allPrice = allPrice.add(duckPrice);
            allNum += orderItem.getGoodsNum();
            table.add(item);
        }
        item = new ArrayList<>();
        item.add("");
        item.add("");
        item.add("");
        item.add("");
        item.add("合计数量");
        item.add(allNum + "");
        item.add("合计金额");
        item.add(allPrice.toString());
        table.add(item);
        return table;
    }

    private List<List<String>> getTableItem(List<ErpTempOrderItem> items) {
        List<List<String>> table = new ArrayList<>();
        List<String> head = new ArrayList<>();
        head.add("序号");
        head.add("商品名称");
        head.add("规格");
        head.add("品牌");
        head.add("订购数量");
        head.add("大单位包装数");
        head.add("单价");
        head.add("金额");
        table.add(head);
        List<String> item;
        ErpTempOrderItem orderItem;
        BigDecimal allPrice = new BigDecimal(0);
        int allNum = 0;
        for (int i = 0; i < items.size(); i++) {
            item = new ArrayList<>();
            orderItem = items.get(i);
            item.add(i + 1 + "");
            item.add(orderItem.getGoodsName());
            item.add(orderItem.getGoodsDesc());
            item.add(orderItem.getBrandName());
            item.add(orderItem.getGoodsNum() + "");
            item.add(orderItem.getNumberUnit());
            item.add(orderItem.getGoodsPrice().toString());
            item.add(orderItem.getGoodsAllPrice().toString());
            allPrice = allPrice.add(orderItem.getGoodsAllPrice());
            allNum += orderItem.getGoodsNum();
            table.add(item);
        }
        item = new ArrayList<>();
        item.add("");
        item.add("");
        item.add("");
        item.add("");
        item.add("合计数量");
        item.add(allNum + "");
        item.add("合计金额");
        item.add(allPrice.toString());
        table.add(item);
        return table;
    }


}
